home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
PGM_TOOL
/
TPRCDR10
/
READ.ME
< prev
next >
Wrap
Text File
|
1994-03-11
|
11KB
|
204 lines
TPRecDir.TPU Copyright (c) 1993, 1994 by Tony G. Papadimitriou, M.S.
Instructions for using the TPRecDir.TPU in your own programs.
Hi,
This archive contains the following files:
CRC $7197BD52 ( 1376 bytes) for MAKEFILE for use with MAKE
( 10950 bytes) for READ.ME this file
CRC $5A433BAD ( 5813 bytes) for TPRECDIR.INT TPRecDir interface
CRC $E0FF4E83 ( 9648 bytes) for TPRECDIR.TPU TP60 TPU
CRC $CBDF55DC ( 27424 bytes) for TPUTILS.TPU TP60 TPU used in examples
CRC $B5708767 ( 12384 bytes) for TPRECDIR.TP7 TP70 TPU
CRC $89C8529B ( 40528 bytes) for TPUTILS.TP7 TP70 TPU used in examples
CRC $DBF2FC3E ( 2098 bytes) for COUNT.PAS example
CRC $895BD4CD ( 4538 bytes) for EXTS.PAS example
CRC $6CD3EA3D ( 6929 bytes) for FD.PAS example
CRC $BF842E43 ( 3580 bytes) for LDIR.PAS example
CRC $A1530980 ( 3242 bytes) for MCOPY.PAS example
CRC $081C27E3 ( 2198 bytes) for WHERE.PAS example
CRC $BEBBA27D ( 2983 bytes) for ZAPDIR.PAS example
The TPU file included in this archive is a Turbo Pascal 6.0 unit that allows
you to recursively act on any file in the supplied path. This is done by
setting up a little routine that gets called from the unit in a manner
similar to that the SORT unit by Borland operates.
The source code is not available at this time.
The interface of the unit is found in the file TPRECDIR.INT
An additional unit is included that provides some routines to the example
programs. No documentation is provided for it though.
There are plenty of comments to make any further documentation needless.
Also, there are several test programs that demonstrate how to use the
various routines in the TPRECDIR unit.
However, here's a few extra words.
There are several routines in this unit. Only one is actually needed to do
the work and the other four are just there to make life easier if you ever
need to use them. Most won't even get linked into your programs if you
don't use them because of Turbo Pascal's smart linking.
The main function's header looks like this:
function ForEachFileIn(workPath, { beginning directory, e.g., 'E:\TMP' }
fileMask: String; { file mask, e.g., '*.BAK' }
attr: Word; { file attribute to match }
monitorEsc: Boolean; { if True, an ESC press will cause immediate return }
recurseOn: Boolean; { if True, it will recurse subdirectories }
userRoutine: pointer): Longint;
It could be called as a procedure (with the X option turned on) if you don't
care to know how many matches there were. Any errors will be reported by
the boolean type variable errorsFound. No error codes will be given. You
can check for error codes in your own routine depending on what you're
trying to do.
The parameters are pretty straight forward. The only possibly confusing
part is the one about the userRoutine. This routine is a function that
returns True on success and False otherwise. It has a single parameter
which is of type SearchRec (found in the Dos standard unit). On entry, the
SearchRec variable you define will hold the information about the next match
whether this is a directory or a file. Any directory that matches the
attribute specified and any file that matches both the attribute specified
and the file mask will be passed to your routine through the SearchRec
variable. You can check its attribute and act on it accordingly.
Since this routine uses recursion, you ought to be careful about allocating
enough stack if your trees tend to get too deep. Also, you should be aware
of the order the files are passed to your routine which is the same order
they appear in the directory with the exception that any directories found
in the middle will be processed before the remaining of the current
directory and likewise for the ones below it.
When a subdirectory is finished being recursed it will have its name passed
to your routine so that you may process the directory itself, e.g., you may
want to remove it, and this is the only time you could anyway because all
the files and directories in it have already been processed and by now you
have already had the chance to erase them.
This unit grabs the exit routine of your program and upon either normal or
abnormal termination will restore the previous directories in all drives
involved, so you don't need to keep track of the current directory in any of
the drives involved.
The next two routines can be used to check a mask prior to passing it to the
ForEachFileIn routine for validity of the characters it contains and for
checking if the mask is equivalent to a global '*.*' which can be very
dangerous in many situations, such as when one is trying to delete the root
and everything under it using *.*. Here are the headers of those two
routines. They both take as a parameter a single string that holds the mask
and return True on a positive check and False otherwise.
{ ╔═══════════╤════════════════════════════════════════════════╗
║ Routine │ IsGlobalMask ║
║ Purpose │ Return True if mask passed is equivalent to ║
║ │ '*.*', such as '*??.???' for example. ║
╚═══════════╧════════════════════════════════════════════════╝ }
function IsGlobalMask(mask: String): Boolean;
{ ╔═══════════╤════════════════════════════════════════════════╗
║ Routine │ IsValidMask ║
║ Purpose │ Return True if mask passed does NOT contain ║
║ │ any of the following characters: ║
║ │ < > = , ; : [ ] / \ + ║
╚═══════════╧════════════════════════════════════════════════╝ }
function IsValidMask(mask: String): Boolean;
The next routine makes a very simple comparison and returns the result as a
boolean value. It compares two attributes and returns true if any of their
bits are in the same position. This is useful for checking if a file is of
a given attribute, e.g. if AttributeMatches(rec.attr,Directory) then.
{ ╔═══════════╤════════════════════════════════════════════════╗
║ Routine │ AttributeMatches ║
║ Purpose │ Return True if attr1 and attr2 have any bits ║
║ │ in common. ║
╚═══════════╧════════════════════════════════════════════════╝ }
function AttributeMatches(attr1,attr2: Word): Boolean;
Another routine lets you know if a filename (without path, i.e., in the form
FILENAME.EXT) matches a given mask. It is used, like some of the rest of
the routines, internally but can also be useful as a standalone routine for
other purposes.
{ ╔═══════════╤════════════════════════════════════════════════╗
║ Routine │ MaskMatches ║
║ Purpose │ Return True if filename can be matched by mask ║
║ Note(s) │ Mask may contain multiple masks delimited by ; ║
╚═══════════╧════════════════════════════════════════════════╝ }
function MaskMatches(filename,mask: String): Boolean;
Two more routines are provided to let you easily get the mask part from a
[command line] path specification and the directory path itself. They are:
{ ╔═══════════╤════════════════════════════════════════════════╗
║ Routine │ GetMask ║
║ Purpose │ Return the multiple masks from a given argument║
╚═══════════╧════════════════════════════════════════════════╝ }
function GetMask(path: String): String;
{ ╔═══════════╤════════════════════════════════════════════════╗
║ Routine │ GetPath ║
║ Purpose │ Return the path/no masks from a given argument ║
╚═══════════╧════════════════════════════════════════════════╝ }
function GetPath(path: String): String;
Finally, the routine MkChDir is used to create and change to a path in a
single step. Note that the complete path can be created with this routine
even if no part of it exists. For example, assuming there's no directory
D:\TMP on your disk, doing a MkChDir('D:\TMP\MISC\WORK\DATA') will create
four directories (D:\TMP, D:\TMP\MISC, D:\TMP\MISC\WORK, and
D:\TMP\MISC\WORK\DATA) and then change to the last one. If the process
fails half-way through, you will be placed inside the last successfully
created/changed to directory and the function will return False. Here's the
header for this function.
{ ╔═══════════╤════════════════════════════════════════════════╗
║ Routine │ MkChDir ║
║ Purpose │ Create (if non-existant) dir tree and change ║
║ │ to it. Returns True on success. ║
╚═══════════╧════════════════════════════════════════════════╝ }
function MkChDir(dir: String): Boolean;
Note: Any time you need to use a mask in either the MaskMatches or the
ForEachFileIn routines, you can use multiple masks by separating them
with semi-colons, e.g., use '*.BAK;*.OLD' to match both files with a
.BAK extension and files with a .OLD extension in a single pass.
Several bugs have been fixed! If you find any yourself, let me know.
If you need more help, study the example programs until you figure them out.
It shouldn't take long!
Hope it comes in handy! Let me know if you find any bugs or have problems
with it in general. Also, if you need to suggest improvements, feel free to
do so at the address below.
╔═══════════════════════════════════════════════════════════════════════════╗
║ Comments to the author may be directed at the address: ║
║ ║
║ Tony G. Papadimitriou ║
║ P.O. Box 14386 ║
║ Athens 115 10 ║
║ GREECE ║
╚═══════════════════════════════════════════════════════════════════════════╝
Tony P.
LEGAL NOTICE:
This software is Freeware which means it is NOT public domain but distributed
freely without money. Its electronic distribution through BBSs or other such
means is encouraged provided no money is requested for its acquisition.
Also, it is forbidden to distribute this software should this file or any of
the remaining files change in any way or be omitted from the archive.
Tony G. Papadimitriou, M.S.